#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include"shep_json.h"

using namespace std;

static int main_ret = 0;  //返回值  0 -- 正常  1 -- 异常
static int test_count = 0;//总测试数
static int test_pass = 0; //通过的测试数

// template<typename T>
// inline void except_eq_base(bool equality, const T& expect, const T& actual){
//     test_count++;
//     if(equality){
//         test_pass++;
//     }
//     else{
//         cerr << __FILE__ << ":" << __LINE__ << ": expect: \" " << expect << " \" actual: \" " << actual
//              << " \"" << endl; 
//         main_ret = 1;
//     }
// }

#define EXPECT_EQ_BASE(equality, expect, actual, format)\
do{\
    test_count++;\
    if(equality)\
        test_pass++;\
    else{\
        fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual);\
        main_ret = 1;\
    }\
}while(0)

// inline void except_eq_int(const int& except, const int& actual){
//     except_eq_base<int>((except == actual), except, actual);
// }

#define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect == actual), expect, actual, "%d")

static void test_parse_null(){
    shep_value v(SHEP_FALSE);
    EXPECT_EQ_INT(SHEP_PARSE_OK, shep_parse(v, "null"));
    EXPECT_EQ_INT(SHEP_NULL, v.get_type());
}

static void test_parse_true(){
    shep_value v(SHEP_FALSE);
    EXPECT_EQ_INT(SHEP_PARSE_OK, shep_parse(v, "true"));
    EXPECT_EQ_INT(SHEP_TRUE, v.get_type()); 
}

static void test_parse_false(){
    shep_value v(SHEP_NULL);
    EXPECT_EQ_INT(SHEP_PARSE_OK, shep_parse(v, "false"));
    EXPECT_EQ_INT(SHEP_FALSE, v.get_type()); 
}

static void test_parse_expect_value(){
    shep_value v(SHEP_FALSE);
    EXPECT_EQ_INT(SHEP_PARSE_EXCEPT_VALUE, shep_parse(v, ""));
    EXPECT_EQ_INT(SHEP_NULL, v.get_type());

    v.set_type(SHEP_FALSE);
    EXPECT_EQ_INT(SHEP_PARSE_EXCEPT_VALUE, shep_parse(v, " "));
    EXPECT_EQ_INT(SHEP_NULL, v.get_type());
}

static void test_parse_invalid_value(){
    shep_value v(SHEP_FALSE);
    EXPECT_EQ_INT(SHEP_PARSE_INVALID_VALUE, shep_parse(v, "nul"));
    EXPECT_EQ_INT(SHEP_NULL, v.get_type());

    v.set_type(SHEP_FALSE);
    EXPECT_EQ_INT(SHEP_PARSE_INVALID_VALUE, shep_parse(v, "?"));
    EXPECT_EQ_INT(SHEP_NULL, v.get_type());
}

static void test_parse_root_not_singular(){
    shep_value v(SHEP_FALSE);
    EXPECT_EQ_INT(SHEP_PARSE_ROOT_NOT_SINGULAR, shep_parse(v, "null x"));
    EXPECT_EQ_INT(SHEP_NULL, v.get_type());
}

static void test_parse() {
    test_parse_null();
    test_parse_true();
    test_parse_false();
    test_parse_expect_value();
    test_parse_invalid_value();
    test_parse_root_not_singular();
}

int main(){
    test_parse();
    cout << test_pass << "/" << test_count << " (" << test_pass * 100.0 / test_count
    << ") passed." << endl;
    return main_ret;
}